#ifndef _TEXTURE_H
#define _TEXTURE_H

#include <string>

#include <gl/glew.h>

#include <FreeImage.h>

#ifdef GALLIUMENGINE_DLL 
#define GALLIUMENGINE_API __declspec( dllexport )
#else
#define GALLIUMENGINE_API __declspec( dllimport )
#endif

namespace GalliumEngine
{

	#ifndef BYTE
	#define BYTE    unsigned char 
	#endif

	namespace TextureType
	{
		enum GALLIUMENGINE_API _TextureType
		{
			DIFFUSE,
			AMBIENT,
			SPECULAR,
			NORMAL
		};
	}

	namespace TextureFiltering
	{

		enum GALLIUMENGINE_API _TextureFiltering
		{
			TEXTURE_FILTER_MAG_NEAREST = 0, // Nearest criterion for magnification
			TEXTURE_FILTER_MAG_BILINEAR, // Bilinear criterion for magnification
			TEXTURE_FILTER_MIN_NEAREST, // Nearest criterion for minification
			TEXTURE_FILTER_MIN_BILINEAR, // Bilinear criterion for minification
			TEXTURE_FILTER_MIN_NEAREST_MIPMAP, // Nearest criterion for minification, but on closest mipmap
			TEXTURE_FILTER_MIN_BILINEAR_MIPMAP, // Bilinear criterion for minification, but on closest mipmap
			TEXTURE_FILTER_MIN_TRILINEAR, // Bilinear criterion for minification on two closest mipmaps, then averaged
		};

	}

	class Texture
	{
	public:
		GALLIUMENGINE_API void createFromData(BYTE* bData, int a_iWidth, int a_iHeight, int a_iBPP, GLenum format, bool bGenerateMipMaps = false);
		
		GALLIUMENGINE_API bool loadTexture(std::string _file, bool generateMipmaps);
		GALLIUMENGINE_API void bindTexture();
		GALLIUMENGINE_API void bindTexture(int textureUnit);
		
		GALLIUMENGINE_API void setFiltering(TextureFiltering::_TextureFiltering _tfMagnification, TextureFiltering::_TextureFiltering _tfMinification);

		GALLIUMENGINE_API int getMinificationFilter();
		GALLIUMENGINE_API int getMagnificationFilter();

		GALLIUMENGINE_API void setSamplerParameter(GLenum parameter, GLenum value);

		GALLIUMENGINE_API GLuint getTextureId();

		GALLIUMENGINE_API int getWidth();
		GALLIUMENGINE_API int getHeight();
		GALLIUMENGINE_API int getBPP();

		GALLIUMENGINE_API void releaseTexture();

		GALLIUMENGINE_API Texture();
	private:
		int width, height, bitsPerPixel; // Texture width, height, and bytes per pixel
		GLuint textureId;
		GLuint samplerId;
		bool mipMapsGenerated;

		int tfMinification, tfMagnification;

		std::string file;
	};

}

#endif